﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using LED_Utils;
using LED_Utils.MultitrackControl;

namespace Maxel.MultitrackControl
{
    public partial class FrameControl : UserControl, ICustomScale,IFramePanel
    {
        public FrameControl()
        {
            InitializeComponent();
        }

        private void splitter1_SplitterMoving(object sender, SplitterEventArgs e)
        {
            //this.Width = this.Left + e.X;
        }

        private void splitter2_SplitterMoving(object sender, SplitterEventArgs e)
        {
            //this.Width = this.Left + e.X;
        }
        bool _isRightSplitterClicked;
        int _initialRightSplitterScreenCoordinatesX;
        int _initialWidth;

        int _currentRightSplitterScreenCoordinatesX;

        private void splitter2_MouseDown(object sender, MouseEventArgs e)
        {
            _isRightSplitterClicked = true;
            //_rightSplitterScreenCoordinatesX = e.X;
            Point screenPoint = MousePosition; //this.PointToScreen(e.Location);
            //Point clientPoint2 = PointToClient(clientPoint);
            //Point clientPoint3 = e.Location;
            _initialRightSplitterScreenCoordinatesX = screenPoint.X;
            _initialWidth = Width;
            assignWidthCount = 0;
        }

        private void splitter2_MouseUp(object sender, MouseEventArgs e)
        {
            _isRightSplitterClicked = false;
        }
        int assignWidthCount = 0;
        private void splitter2_MouseMove(object sender, MouseEventArgs e)
        {
            if (_isRightSplitterClicked)
            {
                Point screenPoint = MousePosition; //this.PointToScreen(e.Location);
                if (_currentRightSplitterScreenCoordinatesX == screenPoint.X)
                    return;

                _currentRightSplitterScreenCoordinatesX = screenPoint.X;

                int preCalculatedWidth = _initialWidth + (_currentRightSplitterScreenCoordinatesX - _initialRightSplitterScreenCoordinatesX);
                if (preCalculatedWidth == Width || preCalculatedWidth < 0)
                    return;
                this.Width = preCalculatedWidth;
                assignWidthCount += 1;
                //label1.Text = string.Format("{5}| Width:{0}, Left:{1}, X1:{2}, X2:{3}, Delta:{4}", this.Width, this.Left, screenPoint.X, _initialRightSplitterScreenCoordinatesX, screenPoint.X - _initialRightSplitterScreenCoordinatesX, assignWidthCount);
            }
        }

        protected override bool ScaleChildren
        {
            get
            {
                return false;
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            base.OnPaintBackground(e);
            //e.ClipRectangle. 
            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            //Brush brush = new LinearGradientBrush(e.ClipRectangle, StartColor, EndColor, LinearGradientMode.Horizontal);     
            //e.Graphics.FillRectangle(brush,e.ClipRectangle);

            Brush brushStart = new SolidBrush(StartColor);
            Brush brushEnd = new SolidBrush(EndColor);

            Rectangle rect = ClientRectangle;
            Point topLeft = rect.Location;
            Point bottomLeft = new Point(rect.Location.X, rect.Location.Y + rect.Height);

            Point topRight = new Point(rect.Location.X + rect.Width, rect.Location.Y);
            Point bottomRight = new Point(rect.Location.X + rect.Width, rect.Location.Y + rect.Height);


            e.Graphics.FillPolygon(brushStart, new Point[] { topLeft, topRight, bottomLeft, topLeft });
            e.Graphics.FillPolygon(brushEnd, new Point[] { bottomLeft, topRight, bottomRight, bottomLeft });

            if (StartColor.ToArgb() != EndColor.ToArgb())
            {
                Pen black = new Pen(Color.Black, 1);
                e.Graphics.DrawLine(black, bottomLeft, topRight);
            }


        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
        }




        #region IFramePanel Members

        private Color _startColor;
        public Color StartColor
        {
            get
            {
                return (Color)ReflectionHelper.GetValue(_frameData, "StartColor");
            }
            set
            {

                //if (StartColor.ToArgb() != value.ToArgb())
                //{
                //    OnFramePanelProperiesChanged();
                //}
                ReflectionHelper.SetValue(_frameData, "StartColor", value);
                //_startColor = value;
            }
        }
        private Color _endColor;
        public Color EndColor
        {
            get
            {
                return (Color)ReflectionHelper.GetValue(_frameData, "EndColor");

                //return _endColor;
            }
            set
            {
                //if (_endColor.ToArgb() != value.ToArgb())
                //{
                //    OnFramePanelProperiesChanged();
                //}
                // _endColor = value;
                ReflectionHelper.SetValue(_frameData, "EndColor", value);

            }
        }

        private float _duration;
        public float Duration
        {
            get
            {
                return (float)ReflectionHelper.GetValue(_frameData, "FrameDuration");

                // return _duration;
            }
            set
            {
                if (Duration != value)
                {
                    OnFramePanelProperiesChanged();
                    this.Width = (int)(value * InitialScale / 100 * ScaleFactor);
                }
                //_duration = value;
                ReflectionHelper.SetValue(_frameData, "FrameDuration", value);

            }
        }

        public event EventHandler FramePanelProperiesChanged;
        private void OnFramePanelProperiesChanged()
        {
            if (FramePanelProperiesChanged != null)
            {
                FramePanelProperiesChanged(this, EventArgs.Empty);
            }
        }



        private void FrameControl_SizeChanged(object sender, EventArgs e)
        {
            if (_isScaling) return;
            Duration = 100 * this.Width / (ScaleFactor * InitialScale);
            Invalidate();
        }

        private object _frameData;
        public object FrameData
        {
            get
            {
                return _frameData;
            }
            set
            {
                _frameData = value;
                if (_frameData != null && _frameData is INotifyPropertyChanged)
                {
                    ((INotifyPropertyChanged)_frameData).PropertyChanged += new PropertyChangedEventHandler(FrameControl_PropertyChanged);
                }
            }
        }

        void FrameControl_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "StartColor" || e.PropertyName == "EndColor")
            {
                Invalidate();
            }
            //MessageBox.Show(e.PropertyName);
        }

        protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
        {
            _isScaling = true;
            base.ScaleControl(factor, specified);
            _isScaling = false;
        }

        #endregion


        #region ICustomScale Members
        private bool _isScaling = false;
        public void PerformScale(int percents)
        {
            //_isScaling = true;
            //this.Width = InitialScale * percents / 100;
            //_isScaling = false;

        }

        private int _initialScale;
        public int InitialScale
        {
            get
            {
                return _initialScale;
            }
            set
            {
                _initialScale = value;
            }
        }


        private float _scaleFactor=1;
        public float ScaleFactor
        {
            get
            {
                return _scaleFactor;
            }
            set
            {
                _scaleFactor = value;
            }

        }

        #endregion
    }

    public interface IFramePanel
    {
        Color StartColor { get; set; }
        Color EndColor { get; set; }
        float Duration { get; set; }
        event EventHandler FramePanelProperiesChanged ;
        object FrameData {get;set;}

    }
}
